<?
  function gethostbyname6($host, $try_a = false) {
        // get AAAA record for $host
        // if $try_a is true, if AAAA fails, it tries for A
        // the first match found is returned
        // otherwise returns false

        $dns = gethostbynamel6($host, $try_a);
        if ($dns == false) { return false; }
        else { return $dns[0]; }
    }

    function gethostbynamel6($host, $try_a = false) {
        // get AAAA records for $host,
        // if $try_a is true, if AAAA fails, it tries for A
        // results are returned in an array of ips found matching type
        // otherwise returns false

        $dns6 = dns_get_record($host, DNS_AAAA);
        if ($try_a == true) {
            $dns4 = dns_get_record($host, DNS_A);
            $dns = array_merge($dns4, $dns6);
        }
        else { $dns = $dns6; }
        $ip6 = array();
        $ip4 = array();
        foreach ($dns as $record) {
            if ($record["type"] == "A") {
                $ip4[] = $record["ip"];
            }
            if ($record["type"] == "AAAA") {
                $ip6[] = $record["ipv6"];
            }
        }
        if (count($ip6) < 1) {
            if ($try_a == true) {
                if (count($ip4) < 1) {
                    return false;
                }
                else {
                    return $ip4;
                }
            }
            else {
                return false;
            }
        }
        else {
            return $ip6;
        }
    }

 class sks_servercollection
 {
  private $servers = array();
  private $created;
  
  public function sks_servercollection()
  {
   $this->created = time();
  }
  
  public function add_server($obj)
  {
   $this->servers[$obj->get_hostname()] = $obj;
  }
  
  public function get_servers()
  {
   return $this->servers;
  }
  
  public function get_time()
  {
   return $this->created;
  }
  
  public function do_add($n,$c=1)
  {
   if(isset($this->servers[$n]) || $c>=10) return false; //$c used to be >= 5
   else return true;
  }
 }
 
 class sks_peer
 {
  private $hostname;
  private $port;
  private $numkeys;
  private $version;
  private $statusok = true;
  private $statusipv6ok = false;
  private $statusfaultreason;
  private $peers = array();
  private $debug = 0;
  private $responsetime = -1;
  private $srvweight;  

  public function get_numkeys() { return $this->numkeys; }
  public function get_version() { return $this->version; }
  public function get_hostname() { return $this->hostname; }
  public function get_port() { return $this->port; }
  public function get_peers() {return $this->peers;}
  public function get_statusok() {return $this->statusok;}
  public function get_serversarr() {return $this->servers;}
  public function get_ipv6() {return $this->statusipv6ok;}
  public function get_responsetime() {return $this->responsetime;}
  public function get_srvweight() {return $this->srvweight;}

  private function microtime_float()
  {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
  }

  public function sks_peer(&$servers, $count, $host,$port=11371)
  {
   $this->hostname = $host;
   $this->port = $port;
   if($this->debug==1)
   {
    echo "\n\n############\n";
    echo $count."\n";
    echo $this->hostname."\n";
    print_r($servers->get_servers());
   }
   // compability for own server
   $host = ($host=="keys.kfwebs.net") ? "10.1.1.3" : $host;
   
   $timestart = $this->microtime_float(); 
   $ch = curl_init("http://$host:$port/pks/lookup?op=stats");
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_TIMEOUT, 10);
   if(($ret=curl_exec($ch))===FALSE)
   {
    curl_close($ch);
    $this->statusok=false;
   }
   else
   {   
    curl_close($ch);
    $this->responsetime = $this->microtime_float() - $timestart; 
    $this->srvweight = (int)((1/($this->responsetime)) * 100);

    // manually correct localhost
    if($this->hostname == "keys.kfwebs.net")
    { 
       $this->srvweight = 200;
    }

    // Set number of keys
    preg_match("/Total number of keys:\s+(\d+)/",$ret,$matches);
    $this->numkeys = $matches[1];
    unset($matches);
    
    // Set SKS version
    preg_match("/Version:.+?([\d\.]+)/",$ret,$matches);
    $this->version = $matches[1];
    unset($matches);
    
    // populate peers
    $ret = strtr($ret,array("\n"=>""));
    preg_match("/<h2>Gossip Peers<\/h2><table>(.*?)<\/table>/",$ret,$matches);
    preg_match_all("/<tr><td>([a-zA-Z0-9\.\-]+)\s+(\d+)/",$matches[1],$matches2);
    
    foreach($matches2[1] as $id=>$hosts)
    {
     $this->peers[] = array($hosts,$matches2[2][$id]);
     if($servers->do_add($hosts,$count))
     {
      $sadd = new sks_peer($servers,$count+1, $hosts);
      $servers->add_server($sadd);
     }
    }
   
    unset($matches); 
    unset($matches2);
   }
   // SETUP ipv6
   //$blacklistv6 = array("keyserver.freenet.de", "gpg-keyserver.de");
   $blacklistv6 = array();

   $ipv6_addy = gethostbyname6(($host=="10.1.1.3" ? "keys.kfwebs.net" : $host));
   if(!is_array($ipv6_addy) && $ipv6_addy !== false && !in_array($host, $blacklistv6))
   {
    $sock = socket_create(AF_INET6, SOCK_STREAM, SOL_TCP);
    if(socket_connect($sock, $ipv6_addy, 11371)) $this->statusipv6ok = true; 
    socket_close($sock);
   }
  }
 }
 
 class sks_stats
 {
  public function sks_stats()
  {
   $str = "graph sks {	size=\"50,50\";graph [label = \"\\n\\nSKS Keyserver map by:\\nhttp://sks-keyservers.net\",fontname=Verdana];node [color=lightblue2, style=filled, fontname=Verdana];";
   $servers = new sks_servercollection;
   $sadd = new sks_peer($servers,1, "keys.kfwebs.net");
   $servers->add_server($sadd);
   
   if(count($servers->get_servers())<3)
   {
    $sadd = new sks_peer($servers,1, "keys2.kfwebs.net");
    $servers->add_server($sadd);
   }

   if(count($servers->get_servers())<3)
   {
    $sadd = new sks_peer($servers,1, "ice.mudshark.org");
    $servers->add_server($sadd);
   }

   if(count($servers->get_servers())<3)
   {
    $sadd = new sks_peer($servers,1, "keyserver.noreply.org");
    $servers->add_server($sadd);
   }
   
   foreach($servers->get_servers() as $server)
   {
    if($server->get_statusok())
    {
     foreach($server->get_peers() as $peer)
     {
      $str .= "\"".$server->get_hostname()."\" -- \"{$peer[0]}\" [color=\"#999999\"];";
     }
    }
    else
    {
     $str .= "\"".$server->get_hostname()."\" [color=rosybrown2,shape=box];";
    }
   }
   $str .= "}";
   
   $status_collection = unserialize(file_get_contents(dirname(__FILE__)."/sks_cache_status_collection.serialized"));
   $status_collection->run($servers);
   
   
   file_put_contents(dirname(__FILE__)."/sks2.dot",$str);
   file_put_contents(dirname(__FILE__)."/sks_cache.serialized",serialize($servers));
   file_put_contents(dirname(__FILE__)."/sks_cache_status_collection.serialized",serialize($status_collection));
  }
 }
?>
